// axios.js
import type { InternalAxiosRequestConfig } from 'axios'
import axios from 'axios'
import { LOGIN_EXPIRED, LOGIN_FAILED } from '@/api/error-code'
import router from '@/router'
import { ACCESS_TOKEN_NAME } from '@/utils/constants'
import { useLocalStorage } from '@vueuse/core'
import { useEnvMode } from '@/utils/env-util'
import { APPLICATION_JSON } from '@/api/content-type'
import { ElMessage } from 'element-plus'

export const accessToken = useLocalStorage(ACCESS_TOKEN_NAME, '')

//baseUrl当开发模式根据环境变量设置，当生产模型就直接使用服务地址
axios.defaults.baseURL = useEnvMode(import.meta.env.VITE_BASE_URL, window.location.origin)
// 默认 post 请求，使用 application/json 形式
// axios.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8"

// 添加请求拦截器
axios.interceptors.request.use(
  function (config: InternalAxiosRequestConfig) {
    // 在发送请求之前做些什么
    if (accessToken.value) {
      config.headers[ACCESS_TOKEN_NAME] = accessToken.value
    }
    return config
  },
  function (error) {
    // 对请求错误做些什么
    console.log(error)
    return Promise.reject(error)
  }
)

// 请求拦截器，内部根据返回值，重新组装，统一管理。
axios.interceptors.response.use(
  (res) => {
    if (typeof res !== 'object' || res.status < 200 || res.status >= 400) {
      ElMessage({
        message: '服务异常!',
        type: 'error'
      })
      // console.log(res)
      return Promise.reject(res)
    }
    if (!res.data || res.data.code === LOGIN_FAILED || res.data.code === LOGIN_EXPIRED) {
      ElMessage({
        message: res.data.msg,
        type: 'error'
      })
      router
        .push({
          path: '/'
        })
        .then(() => undefined)
      return Promise.reject(res)
    }

    if (!res.data || res.data.code !== 0) {
      ElMessage({
        message: res.data.msg,
        type: 'error'
      })
      return Promise.reject(res)
    }
    return res
  },
  () => {
    ElMessage({
      message: '未知错误!',
      type: 'error'
    })
  }
)

export default axios

export function get<T = unknown, R = T, D = unknown>(
  url: string,
  contentType: string = APPLICATION_JSON
): Promise<R> {
  return new Promise((resolve) =>
    axios
      .get(url, {
        headers: {
          'Content-Type': contentType
        }
      })
      .then(
        (response) => {
          resolve(response.data)
        },
        () => {}
      )
  )
}

export function post<T = unknown, R = T, D = unknown>(
  url: string,
  data?: D,
  contentType: string = APPLICATION_JSON
): Promise<R> {
  return new Promise((resolve) =>
    axios
      .post(url, data, {
        headers: {
          'Content-Type': contentType
        }
      })
      .then(
        (response) => {
          resolve(response.data)
        },
        () => {}
      )
  )
}
